<template>
  <fe-page :title="title" @back="goBack">
		<div class="bpmn-container">
			<div class="canvas" id="canvas"></div>
			<div class="panel" id="properties"></div>
		</div>
		<template #extra>
			<input ref="file" type="file" accept=".xml" style="display: none" @change="fileChange" />
			<el-button-group>
        <el-tooltip effect="dark" content="打开文件" placement="top">
          <el-button type="primary" icon="FolderOpened" @click="handleUpload"></el-button>
        </el-tooltip>
        <el-tooltip effect="dark" content="下载xml" placement="top">
          <el-button type="primary" @click="handleDownloadXml"><a ref="downloadLink"><el-icon><Download /></el-icon></a></el-button>
        </el-tooltip>
        <el-tooltip effect="dark" content="下载svg" placement="top">
          <el-button type="primary" @click="handleDownloadSvg"><a ref="downloadSvg"><el-icon><Picture /></el-icon></a></el-button>
        </el-tooltip>
        <el-tooltip effect="dark" content="预览" placement="top">
          <el-button type="primary" icon="View" @click="handlePerviewXML"></el-button>
        </el-tooltip>
			</el-button-group>
			<el-button type="primary" @click="submitForm" :loading="loading">保 存</el-button>
		</template>
		<el-dialog title="xml预览" v-model="perviewXML.show" width="800px" append-to-body>
			<div class="pre-box">
				<el-button type="primary" link icon="DocumentCopy" v-copyText="perviewXML.xml" v-copyText:callback="copyTextSuccess" class="copy-btn">
					复制
				</el-button>
				<pre><code class="hljs" v-html="perviewXML.xml"></code></pre>
			</div>
		</el-dialog>
  </fe-page>
</template>

<script setup name="ProcessAdd">
import BpmnModeler from 'bpmn-js/lib/Modeler.js'
import {
  BpmnPropertiesPanelModule, 
  BpmnPropertiesProviderModule,
	CamundaPlatformPropertiesProviderModule,
	CamundaPlatformTooltipProvider
} from 'bpmn-js-properties-panel'
import camundaModdle from 'camunda-bpmn-moddle/resources/camunda.json'
import 'bpmn-js/dist/assets/bpmn-js.css'
import 'bpmn-js/dist/assets/diagram-js.css'
import 'bpmn-js/dist/assets/bpmn-font/css/bpmn.css'
import 'bpmn-js/dist/assets/bpmn-font/css/bpmn-codes.css'
import 'bpmn-js/dist/assets/bpmn-font/css/bpmn-embedded.css'
import '@bpmn-io/properties-panel/assets/properties-panel.css'
import customTranslate from './customTranslate/customTranslate'
import { generateGUID } from "@/utils/ruoyi"
import hljs from 'highlight.js'
import "highlight.js/styles/atom-one-dark-reasonable.css"

import { getData, addProcess, updateProcess } from "@/api/service/process"

const route = useRoute()
const { proxy } = getCurrentInstance()

const loading = ref(false)
const id = route.params && route.params.id
const title = id? '编辑流程' : '新增流程'
const form = ref({})
let bpmnModeler = null
const perviewXML = ref({
	show: false,
	xml: ''
})

function init() {
	bpmnModeler = new BpmnModeler({
		container: '#canvas',
		propertiesPanel: {
    	parent: '#properties'
  	},
		additionalModules: [
			BpmnPropertiesPanelModule,
			BpmnPropertiesProviderModule,
			CamundaPlatformPropertiesProviderModule,
			CamundaPlatformTooltipProvider,
			customTranslate
		],
		moddleExtensions: {
			camunda: camundaModdle
		}
	})
  if(!id) {
		bpmnModeler.createDiagram().then(res => {
      const canvas = bpmnModeler.get('canvas')
			const rootElement = canvas.getRootElement()
			const modeling = bpmnModeler.get('modeling')
			modeling.updateProperties(rootElement, {
				id: 'Process_' + generateGUID(),
				name: '未命名流程',
				isExecutable: true
			})
    })
	} else {
		getInfo()
	}
}

function getInfo() {
	loading.value = true
	getData(id).then(response => {
		loading.value = false
		let result = response.result || ''
    form.value = result
    bpmnModeler.importXML(result).then(res => {
      proxy.$message.success('加载成功')
    })
  })
}

function handleUpload() {
	proxy.$refs["file"].click()
}

function fileChange() {
  const fileElement = proxy.$refs["file"]
  if (fileElement && fileElement.files) {
    const file = fileElement.files[0]
    const fileReader = new FileReader()
    fileElement.value = ''
    fileReader.onload = (e) => {
      bpmnModeler.importXML(e.target.result).then(err => {
				proxy.$message.success('导入成功')
			})
    }
    fileReader.readAsText(file)
  }
}

async function handleDownloadXml() {
	const downloadLink = proxy.$refs["downloadLink"]
	try {
    const { xml } = await bpmnModeler.saveXML({ format: true })
    setEncoded(downloadLink, 'diagram.xml', xml)
		proxy.$message.success('下载成功')
  } catch (error) {
    proxy.$modal.error('下载失败，请重试')
  }
}

async function handleDownloadSvg() {
	const downloadSvgLink = proxy.$refs["downloadSvg"]
	try {
    const { svg } = await bpmnModeler.saveSVG()
    setEncoded(downloadSvgLink, 'diagram.svg', svg)
		proxy.$message.success('下载成功')
  } catch (error) {
    proxy.$modal.error('下载失败，请重试')
  }
}

function setEncoded(link, name, data) {
  const encodedData = encodeURIComponent(data)
  if (data) {
    link.className += ('active')
    link.setAttribute('href', 'data:application/bpmn20-xml;charset=UTF-8,' + encodedData)
    link.setAttribute('download', name)
  } else {
    link.className.replace('active', '')
  }
}

async function handlePerviewXML() {
	try {
    const { xml } = await bpmnModeler.saveXML({ format: true })
    perviewXML.value.show = true
		perviewXML.value.xml = hljs.highlightAuto(xml).value
  } catch (error) {
    proxy.$modal.error('预览失败，请重试')
  }
}

function copyTextSuccess() {
  proxy.$modal.msgSuccess("复制成功")
}

function getProcessNameFromModel() {
  const canvas = bpmnModeler.get('canvas')
  const rootElement = canvas.getRootElement()
  return (rootElement.businessObject?.name || '未命名流程') + '.bpmn'
}

async function submitForm() {
	loading.value = true
	const { xml } = await bpmnModeler.saveXML({ format: true })
	const processName = getProcessNameFromModel()
	const params = { resName: processName, content: xml}
	if (id != undefined) {
		updateProcess(params).then(response => {
			loading.value = false
			proxy.$modal.msgSuccess("编辑成功")
			goBack()
		}).catch(() => loading.value = false)
	} else {
		addProcess(params).then(response => {
			loading.value = false
			proxy.$modal.msgSuccess("新增成功")
			goBack()
		}).catch(() => loading.value = false)
	}
}

function goBack() {
  const obj = { path: "/service/process", query: { t: Date.now(), current: route.query.current } }
  proxy.$tab.closeOpenPage(obj)
}

onMounted(() => {
  init()
})
</script>

<style lang="scss" scoped>
.bpmn-container{
	width:100%;
  height:100%;
  display: flex;
  background-color: var(--el-color-white);
	.canvas{
		flex: 1;
    height: 100%;
    background: url('')
      repeat !important;
	}
	.panel{
  	width: 250px;
		border: 1px solid var(--tags-item-border, #E4E5E7);
	}
}
.pre-box{
	position: relative;
	.copy-btn{
		position: absolute;
		top: 4px;
		right: 4px;
		z-index: 10;
	}
	.hljs{
    max-height: 700px;
  }
}
</style>